package com.dashu.base.utils.date;

import com.google.common.collect.Lists;
import org.apache.commons.lang3.time.DateUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;

public class TimeUtils {

    static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    static SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    static SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMddHHmmss");
    static SimpleDateFormat sdf3 = new SimpleDateFormat("yyyyMM");
    static SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm");

    /**
     * 获取当前时间
     *
     * @return
     */
    public static String getNowTime() {
        return LocalDateTime.now().toString();
    }


    /**
     * 生成表名
     *
     * @return
     */
    public static String getNowTimeDate() {
        return "kq_" + sdf3.format(new Date(System.currentTimeMillis()));
    }

    /**
     * 时间戳转日期
     *
     * @return
     */
    public static String getNowTimeDate1() {
        return sdf.format(new Date(System.currentTimeMillis()));
    }


    /**
     * 获取当前年份
     *
     * @return
     */
    public static int getNowYear() {
        return LocalDateTime.now().getYear();
    }


    /**
     * 获取当前月
     *
     * @return
     */
    public static int getNowMonth() {
        return LocalDateTime.now().getMonth().getValue();
    }

    /**
     * 获取当前星期
     *
     * @return
     */
    public static String getNowWeek() {

        Date date = new Date();
        SimpleDateFormat dateFm = new SimpleDateFormat("EEEE");
        String currSun = dateFm.format(date);
        return currSun;
    }

    /**
     * 获取当前小时
     *
     * @return
     */
    public static int getNowHour() {
        return LocalDateTime.now().getHour();
    }


    /**
     * 获取当前天
     *
     * @return
     */
    public static int getNowDay() {
        return LocalDateTime.now().getDayOfMonth();
    }

    /**
     * 获取单天+设定时间
     *
     * @return
     */
    public static long getNowDateAnTime(String time) {
        String newTime = getNowTimeDate1() + " " + time;
        return stringTostamp1(newTime);
    }

    /**
     * 获取单天00:00
     *
     * @return
     */
    public static long getNowStart() {
        long current = System.currentTimeMillis();
        long zero = current / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset();//今天零点零分零秒的毫秒数
        return zero;
    }

    /**
     * 获取单天23:59
     *
     * @return
     */
    public static long getNowEnd() {
        long current = System.currentTimeMillis();
        long twelve = current / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset() + 24 * 60 * 60 * 1000 - 1;//今天零点零分零秒的毫秒数
        return twelve;
    }

    /**
     * 获取所选单天00:00
     *
     * @return
     */
    public static long getNowStart1(long current) {
//        long current = System.currentTimeMillis();
        long zero = current / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset();//所选天零点零分零秒的毫秒数
//        long zero = current /(1000*3600*24)*(1000*3600*24)- TimeZone.getDefault().getRawOffset();
        return zero;
    }

    /**
     * 获取所选单天23:59
     *
     * @return
     */
    public static long getNowEnd1(long current) {
//        long current = System.currentTimeMillis();
        long twelve = current / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset() + 24 * 60 * 60 * 1000 - 1;//今天零点零分零秒的毫秒数
//        long twelve = current /(1000*3600*24)*(1000*3600*24)- TimeZone.getDefault().getRawOffset()+ 24 * 60 * 60 * 1000 - 1;//所选天零点零分零秒的毫秒数
        return twelve;
    }



    /**
     * 选择日期开始0时
     *
     * @param time
     * @return
     */
    public static long startInfo(String time) throws ParseException {
        return getStartOfDay(sdf.parse(time)).getTime();
    }

    /**
     * 选择日期结束0时
     *
     * @param time
     * @return
     */
    public static long endInfo(String time) throws ParseException {
        return getEndOfDay(sdf.parse(time)).getTime();
    }


    /**
     * 获取当前时间时间戳
     *
     * @return
     */
    public static long getTimestamp10() {
        return System.currentTimeMillis() / 1000;
    }

    /**
     * 获取当前时间时间戳
     *
     * @return
     */
    public static long getTimestamp13() {
        return System.currentTimeMillis();
    }


    /**
     * 时间戳转日期
     *
     * @param timestamp
     * @return
     */
    public static String stampTodate(long timestamp) {
        return sdf.format(new Date(timestamp));
    }

    /**
     * 时间戳转日期
     *
     * @param timestamp
     * @return
     */
    public static String stampTodatehms(long timestamp) {
        return sdf1.format(new Date(timestamp));
    }


    /**
     * 时间戳转日期
     *
     * @param timestamp
     * @return
     */
    public static String stampTodatehms2(long timestamp) {
        return sdf2.format(new Date(timestamp));
    }


    /**
     * 日期转时间戳
     *
     * @return
     */
    public static long dateTostamp(Date date) {
        return date.getTime();
    }

    /**
     * date 转  年月日
     *
     * @param date
     * @return
     */
    public static String dateTostring1(Date date) {
        return sdf.format(date);
    }


    /**
     *  
     *     * 判断当前日期是星期几<br>  
     *     * <br>  
     *     * @param pTime 修要判断的时间<br>  
     *     * @return dayForWeek 判断结果<br>  
     *     * @Exception 发生异常<br>  
     *     
     */
    public static int dayForWeek(String pTime) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar c = Calendar.getInstance();
        c.setTime(format.parse(pTime));
        int dayForWeek = 0;
        if (c.get(Calendar.DAY_OF_WEEK) == 1) {
            dayForWeek = 7;
        } else {
            dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
        }
        return dayForWeek;
    }

    /**
     * 字符串转时间戳
     *
     * @param time
     * @return
     */
    public static long stringTostamp(String time) {
        try {
            Date date = sdf1.parse(time);
            return date.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 字符串转时间戳
     *
     * @param time
     * @return
     */
    public static long stringTostamp1(String time) {
        try {
            Date date = sdf4.parse(time);
            return date.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
            return 0;
        }
    }


    /**
     * 字符串转时间
     *
     * @param time
     * @return
     */
    public static Date stringTodate(String time) {
        try {
            return sdf.parse(time);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 字符串转时间
     *
     * @param time
     * @return
     */
    public static Date stringTodate1(String time) {
        try {
            return sdf1.parse(time);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 字符串转时间
     *
     * @param time
     * @return
     */
    public static Date stringTodate2(String time) {
        try {
            return sdf2.parse(time);
        } catch (ParseException e) {
            return null;
        }
    }


    public static String dateTostring(Date date) {
        return sdf1.format(date);
    }


    /**
     * 时间相减得出月份
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static Integer getDifMonth(Date startDate, Date endDate) {
        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();
        start.setTime(startDate);
        end.setTime(endDate);
        int result = end.get(Calendar.MONTH) - start.get(Calendar.MONTH);
        int month = (end.get(Calendar.YEAR) - start.get(Calendar.YEAR)) * 12;
        return Math.abs(month + result);
    }


    /**
     * 时间相加
     *
     * @param startTime
     * @param add
     * @return
     */
    public static Date addTime(Date startTime, int add) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startTime);
        calendar.add(Calendar.DAY_OF_MONTH, add);
        return calendar.getTime();
    }


    /**
     * 获取过去第几天的日期
     *
     * @param past
     * @return
     */
    public static String getPastDate(int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - past);
        Date today = calendar.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String result = format.format(today);
        return result;
    }

    /**
     * 获取未来 第 past 天的日期
     *
     * @param past
     * @return
     */
    public static String getFetureDate(int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + past);
        Date today = calendar.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String result = format.format(today);
        return result;
    }

    /**
     * 获得某天最大时间 2020-02-19 23:59:59
     */

    public static Date getEndOfDay(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
        ;
        LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);
        return Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获得某天最小时间 2020-02-17 00:00:00
     */
    public static Date getStartOfDay(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
        LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
        return Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }


    /**
     * 获取本周的第一天
     *
     * @return String
     **/
    public static long getWeekStart() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.WEEK_OF_MONTH, 0);
        cal.set(Calendar.DAY_OF_WEEK, 2);
        Date time = cal.getTime();
        return stringTostamp(sdf.format(time) + " 00:00:00");
    }

    /**
     * 获取本周的最后一天
     *
     * @return String
     **/
    public static long getWeekEnd() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_WEEK, cal.getActualMaximum(Calendar.DAY_OF_WEEK));
        cal.add(Calendar.DAY_OF_WEEK, 1);
        Date time = cal.getTime();
        return stringTostamp(sdf.format(time) + " 23:59:59");

    }


    /**
     * todo获取近七天日期
     */
    public static List<String> getSevenDate() {
        List<String> dateList = Lists.newArrayList();
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_WEEK, cal.getActualMaximum(Calendar.DAY_OF_WEEK));
        cal.add(Calendar.DAY_OF_WEEK, 1);
        Date time = cal.getTime();
        for (int i = 0; i < 7; i++) {
            Date date = DateUtils.addDays(time, -i);
            String formatDate = sdf.format(date);
            dateList.add(formatDate);
        }
        return dateList;
    }


    /**
     * 获取本月开始日期
     *
     * @return String
     **/
    public static long getMonthStart() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, 0);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date time = cal.getTime();
        return stringTostamp(sdf.format(time) + " 00:00:00");
    }

    /**
     * 获取本月最后一天
     *
     * @return String
     **/
    public static long getMonthEnd() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date time = cal.getTime();
        return stringTostamp(sdf.format(time) + " 23:59:59");
    }

    /**
     * 获取所选本月开始日期
     *
     * @return String
     **/
    public static long getMonthStart1(long newtime) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(newtime);
        cal.add(Calendar.MONTH, 0);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date time = cal.getTime();
        return stringTostamp(sdf.format(time) + " 00:00:00");
    }

    /**
     * 获取所选本月最后一天
     *
     * @return String
     **/
    public static long getMonthEnd1(long newtime) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(newtime);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date time = cal.getTime();
        return stringTostamp(sdf.format(time) + " 23:59:59");
    }


    /**
     * 获取30天以前的时间，同样是比较常用的
     */

    public static String getThirtyDaysAgo(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.add(calendar.DATE, -30);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
    }


    /**
     * 给时间加上几个小时
     *
     * @param day  当前时间 格式：yyyy-MM-dd HH:mm:ss
     * @param hour 需要加的时间
     * @return
     */
    public static String addDateMinut(String day, int hour) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = format.parse(day);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        if (date == null)
            return "";
//        System.out.println("front:" + format.format(date)); //显示输入的日期
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.SECOND, hour);// 24小时制
        date = cal.getTime();
//        System.out.println("after:" + format.format(date));  //显示更新后的日期
        cal = null;
        return format.format(date);

    }


    public static void main(String[] args) throws ParseException {
        List<String> ss = getSevenDate();
        System.out.println(getWeekStart());
        System.out.println(getWeekEnd());
        System.out.println(getMonthStart());
        System.out.println(getMonthEnd());
        List<String> list = getAllTheDateOftheMonth(new Date());
        for (String date : list) {
            System.out.println(date);
        }
    }

    public static List<String> getAllTheDateOftheMonth(Date date) {
        List<String> list = Lists.newArrayList();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DATE, 1);
        int month = cal.get(Calendar.MONTH);
        while (cal.get(Calendar.MONTH) == month) {
            list.add(dateTostring1(cal.getTime()));
            cal.add(Calendar.DATE, 1);
        }
        return list;
    }

}
